package ink.xiaobaibai.service;

import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.core.conditions.update.UpdateWrapper;
import ink.xiaobaibai.emqtt.EMqttManager;
import ink.xiaobaibai.emqtt.EMqttService;
import ink.xiaobaibai.emqtt.MyMqttCallback;
import ink.xiaobaibai.entity.*;
import ink.xiaobaibai.enumOxy.BusinessType;
import ink.xiaobaibai.enumOxy.DeviceStatus;
import lombok.extern.slf4j.Slf4j;
import org.eclipse.paho.client.mqttv3.IMqttDeliveryToken;
import org.eclipse.paho.client.mqttv3.MqttMessage;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.boot.ApplicationArguments;
import org.springframework.boot.ApplicationRunner;
import org.springframework.data.redis.core.StringRedisTemplate;
import org.springframework.stereotype.Service;

import java.util.concurrent.TimeUnit;


/**
 * @description: 故障监听服务
 * @author: 小白白
 * @create: 2021-06-16
 **/

@Slf4j
@Service
public class FaultMonitoringService implements ApplicationRunner {

    @Autowired
    private IOzoneDeviceService ozoneDeviceService;

    @Autowired
    private IOxygenDeviceService oxygenDeviceService;

    @Autowired
    private IMonthlyfeeDeviceService monthlyfeeDeviceService;

    @Autowired
    private IMonthlyOxygenDeviceService monthlyOxygenDeviceService;

    @Autowired
    private IBuyOzoneDeviceService buyOzoneDeviceService;

    @Autowired
    private IBuyOxygenDeviceService buyOxygenDeviceService;

    @Autowired
    private ISmsCodeSender smsCodeSender;

    @Autowired
    private IAdminUserService adminUserService;

    @Autowired
    private IFaultTerminalService faultTerminalService;

    @Autowired
    private StringRedisTemplate stringRedisTemplate;

    @Autowired
    private IFreeOzoneDeviceService freeOzoneDeviceService;

    @Autowired
    private IFreeOxygenDeviceService freeOxygenDeviceService;

    @Value("${myApp.dev}")
    private String devFlag;

    private String adminPhone = "13723574890";

    @Override
    public void run(ApplicationArguments args) throws Exception {
        String faultSubTopic = "fault-sub";
        String faultPubTopic = "fault-pub";
        String clientId;

        if (this.devFlag.equals("1")) {
            log.info("开发环境");
            clientId = "faultClientId-Dev";
        } else if (this.devFlag.equals("2")) {
            log.info("不开启mqtt");
            return;
        } else {
            clientId = "faultClientId";
        }

        EMqttService eMqttService = EMqttManager.getClient(faultSubTopic, faultPubTopic, clientId, new FaultCallBack());
        eMqttService.start();
    }

    class FaultCallBack extends MyMqttCallback {

        @Override
        protected void connectionLost2(Throwable throwable) {

        }

        @Override
        protected void messageArrived2(String s, MqttMessage mqttMessage) {
            /**
             * 故障有6个
             * 1.定点 臭氧 氧气
             * 2.包月 臭氧 氧气
             * 3.购买 臭氧 氧气
             */

            // redis存放近期故障的机器码,如果遇到重复不处理 时间:15分钟
            String deviceCode = new String(mqttMessage.getPayload());
            Boolean hasKey = FaultMonitoringService.this.stringRedisTemplate.hasKey(deviceCode);
            if (hasKey != null && hasKey) {
                // 加时
                FaultMonitoringService.this.stringRedisTemplate.expire(deviceCode, 10, TimeUnit.MINUTES);
                return;
            }
            if (this.onePay(deviceCode)) {
                log.error("定点机器故障,机器码:" + deviceCode);
                //定点业务: 需要修改对应的状态,让机器不能启动,所以需要在内部特殊处理
            } else if (this.monthly(deviceCode)) {
                log.error("包月机器故障,机器码:" + deviceCode);
            } else if (this.buy(deviceCode)) {
                log.error("购买机器故障,机器码:" + deviceCode);
            } else if (this.free(deviceCode)) {
                log.error("酒店机器故障,机器码:" + deviceCode);
            } else {
                log.error("未知机器故障,机器码:" + deviceCode);
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(FaultMonitoringService.this.adminPhone, deviceCode, false, BusinessType.ONEPAY);
            }
            FaultMonitoringService.this.stringRedisTemplate.opsForValue().set(deviceCode, "1", 10, TimeUnit.MINUTES);
        }

        @Override
        protected void deliveryComplete2(IMqttDeliveryToken iMqttDeliveryToken) {

        }

        private boolean onePay(String deviceCode) {

            UpdateWrapper<OzoneDevice> u1 = new UpdateWrapper<>();
            u1.set("status", DeviceStatus.FAULT.getStatus());
            u1.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.ozoneDeviceService.update(u1)) {
                QueryWrapper<OzoneDevice> q1 = new QueryWrapper<>();
                q1.select("admin_user_id");
                q1.eq("device_code", deviceCode);
                String adminPhone = this.getAdminPhone(FaultMonitoringService.this.ozoneDeviceService.getOne(q1).getAdminUserId());
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(adminPhone, deviceCode, false, BusinessType.ONEPAY);
                FaultMonitoringService.this.faultTerminalService.onePayFaultToOzone(deviceCode);
                return true;
            }

            UpdateWrapper<OxygenDevice> u2 = new UpdateWrapper<>();
            u2.set("status", DeviceStatus.FAULT.getStatus());
            u2.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.oxygenDeviceService.update(u2)) {
                //修改所有臭氧机
                QueryWrapper<OxygenDevice> q1 = new QueryWrapper<>();
                q1.select("id", "admin_user_id");
                q1.eq("device_code", deviceCode);
                OxygenDevice oxygenDevice = FaultMonitoringService.this.oxygenDeviceService.getOne(q1);
                Integer id = oxygenDevice.getId();
                UpdateWrapper<OzoneDevice> u3 = new UpdateWrapper<>();
                u3.set("status", DeviceStatus.FAULT.getStatus());
                u3.eq("oxygen_id", id);
                FaultMonitoringService.this.ozoneDeviceService.update(u3);
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(this.getAdminPhone(oxygenDevice.getAdminUserId()), deviceCode, true, BusinessType.ONEPAY);
                FaultMonitoringService.this.faultTerminalService.onePayFaultToOxygen(deviceCode);
                return true;
            }

            return false;
        }

        private boolean monthly(String deviceCode) {

            QueryWrapper<MonthlyfeeDevice> q0 = new QueryWrapper<>();
            q0.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.monthlyfeeDeviceService.count(q0) != 0) {
                QueryWrapper<MonthlyfeeDevice> q1 = new QueryWrapper<>();
                q1.select("admin_user_id", "dep_id");
                q1.eq("device_code", deviceCode);
                MonthlyfeeDevice monthlyfeeDevice = FaultMonitoringService.this.monthlyfeeDeviceService.getOne(q1);
                String adminPhone = this.getAdminPhone(monthlyfeeDevice.getAdminUserId());
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(adminPhone, deviceCode, false, BusinessType.MON);
                FaultMonitoringService.this.faultTerminalService.save(new FaultTerminal(deviceCode, "包月臭氧机器故障", monthlyfeeDevice.getAdminUserId(), monthlyfeeDevice.getDepId()));
                return true;
            }

            QueryWrapper<MonthlyOxygenDevice> q2 = new QueryWrapper<>();
//            u2.set("status",DeviceStatus.FAULT.getStatus());
            q2.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.monthlyOxygenDeviceService.count(q2) != 0) {
                QueryWrapper<MonthlyOxygenDevice> q1 = new QueryWrapper<>();
                q1.select("id", "admin_user_id", "dep_id");
                q1.eq("device_code", deviceCode);
                MonthlyOxygenDevice oxygenDevice = FaultMonitoringService.this.monthlyOxygenDeviceService.getOne(q1);
                //修改所有臭氧机
//                Integer id = oxygenDevice.getId();
//                UpdateWrapper<MonthlyfeeDevice> u3=new UpdateWrapper<>();
//                u3.set("status",DeviceStatus.FAULT.getStatus());
//                u3.eq("oxygen_id",id);
//                monthlyfeeDeviceService.update(u3);
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(this.getAdminPhone(oxygenDevice.getAdminUserId()), deviceCode, true, BusinessType.MON);
                FaultMonitoringService.this.faultTerminalService.save(new FaultTerminal(deviceCode, "包月氧气机器故障", oxygenDevice.getAdminUserId(), oxygenDevice.getAdminDepId()));
                return true;
            }


            return false;
        }

        private boolean buy(String deviceCode) {

            QueryWrapper<BuyOzoneDevice> q0 = new QueryWrapper<>();
//            u1.set("status",DeviceStatus.FAULT.getStatus());
            q0.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.buyOzoneDeviceService.count(q0) != 0) {
                QueryWrapper<BuyOzoneDevice> q1 = new QueryWrapper<>();
                q1.select("admin_user_id", "dep_id");
                q1.eq("device_code", deviceCode);
                BuyOzoneDevice buyOzoneDevice = FaultMonitoringService.this.buyOzoneDeviceService.getOne(q1);
                String adminPhone = this.getAdminPhone(buyOzoneDevice.getAdminUserId());
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(adminPhone, deviceCode, false, BusinessType.BUY);
                FaultMonitoringService.this.faultTerminalService.save(new FaultTerminal(deviceCode, "购买臭氧机器故障", buyOzoneDevice.getAdminUserId(), buyOzoneDevice.getDepId()));
                return true;
            }

            UpdateWrapper<BuyOxygenDevice> q2 = new UpdateWrapper<>();
            q2.set("status", DeviceStatus.FAULT.getStatus());
            q2.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.buyOxygenDeviceService.update(q2)) {
                QueryWrapper<BuyOxygenDevice> q1 = new QueryWrapper<>();
                q1.select("id", "admin_user_id", "dep_id");
                q1.eq("device_code", deviceCode);
                BuyOxygenDevice oxygenDevice = FaultMonitoringService.this.buyOxygenDeviceService.getOne(q1);
                //修改所有臭氧机
//                Integer id = oxygenDevice.getId();
//                UpdateWrapper<BuyOzoneDevice> u3=new UpdateWrapper<>();
//                u3.set("status",DeviceStatus.FAULT.getStatus());
//                u3.eq("oxygen_id",id);
//                buyOzoneDeviceService.update(u3);
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(this.getAdminPhone(oxygenDevice.getAdminUserId()), deviceCode, true, BusinessType.BUY);
                FaultMonitoringService.this.faultTerminalService.save(new FaultTerminal(deviceCode, "购买氧气机器故障", oxygenDevice.getAdminUserId(), oxygenDevice.getDepId()));
                return true;
            }

            return false;
        }

        private boolean free(String deviceCode) {

            QueryWrapper<FreeOzoneDevice> q1 = new QueryWrapper<>();
            q1.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.freeOzoneDeviceService.count(q1) != 0) {
                QueryWrapper<FreeOzoneDevice> q2 = new QueryWrapper<>();
                q2.select("admin_user_id", "dep_id");
                q2.eq("device_code", deviceCode);
                FreeOzoneDevice freeOzoneDevice = FaultMonitoringService.this.freeOzoneDeviceService.getOne(q2);
                String adminPhone = this.getAdminPhone(freeOzoneDevice.getAdminUserId());
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(adminPhone, deviceCode, false, BusinessType.BUY);
                FaultMonitoringService.this.faultTerminalService.save(new FaultTerminal(deviceCode, "酒店臭氧机器故障", freeOzoneDevice.getAdminUserId(), freeOzoneDevice.getDepId()));
                return true;
            }

            QueryWrapper<FreeOxygenDevice> q3 = new QueryWrapper<>();
            q3.eq("device_code", deviceCode);
            if (FaultMonitoringService.this.freeOxygenDeviceService.count(q3) != 0) {
                QueryWrapper<FreeOxygenDevice> q2 = new QueryWrapper<>();
                q2.select("admin_user_id", "dep_id");
                q2.eq("device_code", deviceCode);
                FreeOxygenDevice freeOxygenDevice = FaultMonitoringService.this.freeOxygenDeviceService.getOne(q2);
                String adminPhone = this.getAdminPhone(freeOxygenDevice.getAdminUserId());
                FaultMonitoringService.this.smsCodeSender.sendFaultMessage(adminPhone, deviceCode, true, BusinessType.BUY);
                FaultMonitoringService.this.faultTerminalService.save(new FaultTerminal(deviceCode, "酒店氧气机器故障", freeOxygenDevice.getAdminUserId(), freeOxygenDevice.getDepId()));
                return true;
            }

            return false;
        }

        private String getAdminPhone(Integer adminUserId) {
            QueryWrapper<AdminUser> q1 = new QueryWrapper<>();
            q1.select("user_phone");
            q1.eq("id", adminUserId);
            AdminUser adminUser = FaultMonitoringService.this.adminUserService.getOne(q1);
            if (adminUser == null) {
                log.error("对应用户不存在");
                return FaultMonitoringService.this.adminPhone;
            }
            return adminUser.getUserPhone();
        }

    }


}
